package com.ruoyi.dataStatistics.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.dataBase.domain.IndustrialTransportProject;
import com.ruoyi.dataBase.mapper.IndustrialTransportProjectMapper;
import com.ruoyi.dataStatistics.domain.*;
import com.ruoyi.dataStatistics.service.BigScreenStatisticsService;
import com.ruoyi.reportInfo.domain.*;
import com.ruoyi.reportInfo.domain.bo.IndustrialParkBo;
import com.ruoyi.reportInfo.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class BigScreenStatisticsServiceImpl implements BigScreenStatisticsService {

    @Autowired
    IndustrialParkMapper industrialParkMapper;
    @Autowired
    IndustrialLogisticsCompanyLineOperationMapper industrialLogisticsCompanyLineOperationMapper;
    @Autowired
    IndustrialLogisticsCompanyMapper industrialLogisticsCompanyMapper;
    @Autowired
    IndustrialLogisticsCompanyStoreMapper industrialLogisticsCompanyStoreMapper;
    @Autowired
    IndustrialLogisticsCompanyLineMapper industrialLogisticsCompanyLineMapper;
    @Autowired
    IndustrialStationMapper industrialStationMapper;
    @Autowired
    IndustrialStationOperationInfoMapper industrialStationOperationInfoMapper;
    @Autowired
    IndustrialTransportProjectMapper industrialTransportProjectMapper;


    @Override
    public LogisticsInfrastructureReportVo getLogisticsInfrastructureReport() {

        LogisticsInfrastructureReportVo report = new LogisticsInfrastructureReportVo();

        // 1. 统计交通物流项目数量
        List<IndustrialTransportProject> projectList = industrialTransportProjectMapper.selectList(null);
        report.setLogisticsProjectTotalCount(projectList.size());

        // 2. 统计园区数量和总面积
        List<IndustrialPark> parkList = industrialParkMapper.selectList(null);
        report.setParkTotalCount(parkList.size());
        double totalArea = parkList.stream()
            .map(p -> Optional.ofNullable(p.getArea()).orElse(0.0))
            .reduce(0.0, Double::sum);
        report.setParkTotalArea(new BigDecimal(totalArea).setScale(2, RoundingMode.HALF_UP).doubleValue());

        // 3. 统计园区入驻企业总数
        List<IndustrialLogisticsCompany> companyList = industrialLogisticsCompanyMapper.selectList(null);
        report.setParkTotalEnterprises(companyList.size());

        // 4. 统计园区专线总数
        List<IndustrialLogisticsCompanyLineOperation> companyLineOps = industrialLogisticsCompanyLineOperationMapper.selectList(null);
        report.setParkTotalSpecialLines(companyLineOps.size());

        // 5. 统计场站总数
        List<IndustrialStation> stationList = industrialStationMapper.selectList(null);
        report.setStationTotalCount(stationList.size());

        return report;
    }

    @Override
    public IndustrialParkAnalysisVo logisticsParkAnalysis(IndustrialParkBo bo) {

        Date statisticalYearDate = bo.getStatisticalYearDate();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(statisticalYearDate);
        int year = calendar.get(Calendar.YEAR);
        // 查询所有园区
        List<IndustrialPark> parkList = industrialParkMapper.selectList(new LambdaQueryWrapper<>());

        // 按园区类型分组（String: "1" ~ "4"）
        Map<String, List<IndustrialPark>> typeMap =
            parkList.stream().collect(Collectors.groupingBy(IndustrialPark::getParkType));

        // 初始化 12 个月全部为 0
        List<Double> zeroList = new ArrayList<>(Collections.nCopies(12, 0.0));

        IndustrialParkAnalysisVo vo = new IndustrialParkAnalysisVo();
        vo.setFreightVolume1(new ArrayList<>(zeroList));
        vo.setFreightVolume2(new ArrayList<>(zeroList));
        vo.setFreightVolume3(new ArrayList<>(zeroList));
        vo.setFreightVolume4(new ArrayList<>(zeroList));

        // ========= 遍历类型（String 类型）=========
        for (String type : Arrays.asList("1", "2", "3", "4")) {

            List<IndustrialPark> list = typeMap.getOrDefault(type, Collections.emptyList());
            if (list.isEmpty()) continue;

            List<String> parkIds = list.stream().map(IndustrialPark::getId).collect(Collectors.toList());

            /*-----------------------------------------
             * 1. 查询此类型园区下的场站
             *-----------------------------------------*/
            List<IndustrialStation> stationList =
                industrialStationMapper.selectList(
                    new LambdaQueryWrapper<IndustrialStation>()
                        .in(IndustrialStation::getBelongParkId, parkIds)
                );

            List<String> stationIds = stationList.stream()
                .map(IndustrialStation::getId)
                .collect(Collectors.toList());

            /*-----------------------------------------
             * 2. 查询此类型园区下的企业
             *-----------------------------------------*/
            List<IndustrialLogisticsCompany> companyList =
                industrialLogisticsCompanyMapper.selectList(
                    new LambdaQueryWrapper<IndustrialLogisticsCompany>()
                        .in(IndustrialLogisticsCompany::getBelongParkId, parkIds)
                );

            List<String> companyIds = companyList.stream()
                .map(IndustrialLogisticsCompany::getId)
                .collect(Collectors.toList());

            /*-----------------------------------------
             * 3. 查询场站运营（按月汇总）
             *-----------------------------------------*/
            Map<Integer, BigDecimal> stationMonthMap = new HashMap<>();

            if (!stationIds.isEmpty()) {
                List<IndustrialStationOperationInfo> stationOps =
                    industrialStationOperationInfoMapper.selectList(
                        new LambdaQueryWrapper<IndustrialStationOperationInfo>()
                            .in(IndustrialStationOperationInfo::getStationId, stationIds)
                            .apply("YEAR(report_collect_date) = {0}", year)
                    );

                stationOps.forEach(op -> {
                    int m = op.getReportDate().toInstant().atZone(ZoneId.systemDefault()).getMonthValue();
                    BigDecimal val = Optional.ofNullable(op.getFreightVolume()).orElse(BigDecimal.ZERO);
                    stationMonthMap.merge(m, val, BigDecimal::add);
                });
            }

            /*-----------------------------------------
             * 4. 查询企业专线运营（按月汇总）
             *-----------------------------------------*/
            Map<Integer, BigDecimal> companyMonthMap = new HashMap<>();

            if (!companyIds.isEmpty()) {
                List<IndustrialLogisticsCompanyLineOperation> companyOps =
                    industrialLogisticsCompanyLineOperationMapper.selectList(
                        new LambdaQueryWrapper<IndustrialLogisticsCompanyLineOperation>()
                            .in(IndustrialLogisticsCompanyLineOperation::getCompanyId, companyIds)
                            .apply("YEAR(report_collect_date) = {0}", year)
                    );

                companyOps.forEach(op -> {
                    int m = op.getReportDate().toInstant().atZone(ZoneId.systemDefault()).getMonthValue();
                    BigDecimal val = Optional.ofNullable(op.getFreightVolume()).orElse(BigDecimal.ZERO);
                    companyMonthMap.merge(m, val, BigDecimal::add);
                });
            }

            /*-----------------------------------------
             * 5. 合计（场站 + 企业） → 填满 1~12 月
             *-----------------------------------------*/
            List<Double> monthList = new ArrayList<>();
            for (int m = 1; m <= 12; m++) {
                BigDecimal total = stationMonthMap.getOrDefault(m, BigDecimal.ZERO)
                    .add(companyMonthMap.getOrDefault(m, BigDecimal.ZERO))
                    .setScale(2, RoundingMode.HALF_UP);   // ⭐ 保留两位小数

                monthList.add(total.doubleValue());
            }

            /*-----------------------------------------
             * 6. 根据类型放入 vo
             *-----------------------------------------*/
            switch (type) {
                case "1":
                    vo.setFreightVolume1(monthList);
                    break;
                case "2":
                    vo.setFreightVolume2(monthList);
                    break;
                case "3":
                    vo.setFreightVolume3(monthList);
                    break;
                case "4":
                    vo.setFreightVolume4(monthList);
                    break;
            }
        }

        return vo;
    }

    @Override
    public LogisticServiceResourcesVo getLogisticServiceResourcesReport() {

        LogisticServiceResourcesVo vo = new LogisticServiceResourcesVo();

        // 1. 查询所有企业、专线、仓库
        List<IndustrialLogisticsCompany> companyList = industrialLogisticsCompanyMapper.selectList(null);
        List<IndustrialLogisticsCompanyLine> lineList = industrialLogisticsCompanyLineMapper.selectList(null);
        List<IndustrialLogisticsCompanyStore> storeList = industrialLogisticsCompanyStoreMapper.selectList(null);

        /*
         * =============================================================
         * 2. 企业类型分析 CompanyTypeAnalysis
         * =============================================================
         */
        CompanyTypeAnalysis companyType = new CompanyTypeAnalysis();

        companyType.setTransportCompanyCount((int) companyList.stream().filter(c -> "1".equals(c.getCompanyType())).count());
        companyType.setStorageCompanyCount((int) companyList.stream().filter(c -> "2".equals(c.getCompanyType())).count());
        companyType.setExpressCompanyCount((int) companyList.stream().filter(c -> "3".equals(c.getCompanyType())).count());
        companyType.setComprehensiveCompanyCount((int) companyList.stream().filter(c -> "4".equals(c.getCompanyType())).count());
        companyType.setTotalCompanyCount(companyList.size());

        vo.setCompanyTypeAnalysis(companyType);


        /*
         * =============================================================
         * 3. 企业专线类型分析 CompanyLineTypeAnalysis
         * =============================================================
         */
        CompanyLineTypeAnalysis lineType = new CompanyLineTypeAnalysis();

        lineType.setIntraProvincialLineCount((int) lineList.stream().filter(l -> l.getProvinceType() != null && l.getProvinceType() == 1L).count());
        lineType.setInterProvincialLineCount((int) lineList.stream().filter(l -> l.getProvinceType() != null && l.getProvinceType() == 2L).count());
        lineType.setTotalLineCount(lineList.size());

        vo.setCompanyLineTypeAnalysis(lineType);


        /*
         * =============================================================
         * 4. 仓储能力分析 StorageCapacityAnalysis
         * =============================================================
         */
        StorageCapacityAnalysis capacity = new StorageCapacityAnalysis();

        int generalCount = 0;
        BigDecimal generalArea = BigDecimal.ZERO;

        int coldCount = 0;
        BigDecimal coldArea = BigDecimal.ZERO;

        int bulkCount = 0;

        int expressCenterCount = 0;
        BigDecimal expressArea = BigDecimal.ZERO;

        for (IndustrialLogisticsCompanyStore s : storeList) {

            BigDecimal area = s.getArea() == null ? BigDecimal.ZERO : s.getArea();

            switch (s.getStoreType()) {
                case "1": // 普货
                    generalCount++;
                    generalArea = generalArea.add(area);
                    break;
                case "2": // 冷链
                    coldCount++;
                    coldArea = coldArea.add(area);
                    break;
                case "3": // 散货堆场
                    bulkCount++;
                    break;
                case "4": // 快递分拨
                    expressCenterCount++;
                    expressArea = expressArea.add(area);
                    break;
            }
        }

        capacity.setGeneralGoodsWarehouseCount(generalCount);
        capacity.setGeneralGoodsWarehouseArea(generalArea.setScale(2, RoundingMode.HALF_UP));

        capacity.setColdStorageWarehouseCount(coldCount);
        capacity.setColdStorageWarehouseArea(coldArea.setScale(2, RoundingMode.HALF_UP));

        capacity.setBulkCargoYardCount(bulkCount);

        capacity.setExpressDistributionCenterCount(expressCenterCount);
        capacity.setExpressDistributionCenterArea(expressArea.setScale(2, RoundingMode.HALF_UP));

        vo.setStorageCapacityAnalysis(capacity);


        /*
         * =============================================================
         * 5. 仓储货物分析 StorageGoodsAnalysis（多选拆分）
         * =============================================================
         */
        StorageGoodsAnalysis goods = new StorageGoodsAnalysis();

        // 计数 + 面积
        BigDecimal a1 = BigDecimal.ZERO;
        int g1 = 0;
        BigDecimal a2 = BigDecimal.ZERO;
        int g2 = 0;
        BigDecimal a3 = BigDecimal.ZERO;
        int g3 = 0;
        BigDecimal a4 = BigDecimal.ZERO;
        int g4 = 0;
        BigDecimal a5 = BigDecimal.ZERO;
        int g5 = 0;
        BigDecimal a6 = BigDecimal.ZERO;
        int g6 = 0;
        BigDecimal a7 = BigDecimal.ZERO;
        int g7 = 0;

        for (IndustrialLogisticsCompanyStore s : storeList) {

            BigDecimal area = s.getArea() == null ? BigDecimal.ZERO : s.getArea();

            // 货物类型解析结果
            List<String> list = new ArrayList<>();

            String goodsType = s.getGoodsType();
            if (StrUtil.isBlank(goodsType)) {
                continue;    // 🔥 不返回整个方法，只跳过当前项
            }

            // 判断是否 JSON 数组格式
            if (JSONUtil.isTypeJSONArray(goodsType)) {
                list = JSONUtil.toList(JSONUtil.parseArray(goodsType), String.class);
            } else {
                // 否则单个字符串处理
                list = Collections.singletonList(goodsType);
            }

            // 多选拆分
            for (String gt : list) {
                switch (gt) {
                    case "1":
                        g1++;
                        a1 = a1.add(area);
                        break;
                    case "2":
                        g2++;
                        a2 = a2.add(area);
                        break;
                    case "3":
                        g3++;
                        a3 = a3.add(area);
                        break;
                    case "4":
                        g4++;
                        a4 = a4.add(area);
                        break;
                    case "5":
                        g5++;
                        a5 = a5.add(area);
                        break;
                    case "6":
                        g6++;
                        a6 = a6.add(area);
                        break;
                    case "7":
                        g7++;
                        a7 = a7.add(area);
                        break;
                }
            }
        }

        // =====================================================
        // 写入分析结果
        // =====================================================

        goods.setGeneralGoodsWarehouseCount(g1);
        goods.setGeneralGoodsWarehouseArea(a1.setScale(2, RoundingMode.HALF_UP));

        goods.setFreshGoodsWarehouseCount(g2);
        goods.setFreshGoodsWarehouseArea(a2.setScale(2, RoundingMode.HALF_UP));

        goods.setBuildingMaterialsWarehouseCount(g3);
        goods.setBuildingMaterialsWarehouseArea(a3.setScale(2, RoundingMode.HALF_UP));

        goods.setMachineryManufacturingWarehouseCount(g4);
        goods.setMachineryManufacturingWarehouseArea(a4.setScale(2, RoundingMode.HALF_UP));

        goods.setPharmaceuticalChemicalWarehouseCount(g5);
        goods.setPharmaceuticalChemicalWarehouseArea(a5.setScale(2, RoundingMode.HALF_UP));

        goods.setBulkCommodityWarehouseCount(g6);
        goods.setBulkCommodityWarehouseArea(a6.setScale(2, RoundingMode.HALF_UP));

        goods.setExpressItemsWarehouseCount(g7);
        goods.setExpressItemsWarehouseArea(a7.setScale(2, RoundingMode.HALF_UP));

        // 设置到 VO
        vo.setStorageGoodsAnalysis(goods);



        /*
         * =============================================================
         * 6. 运力分析 TransportCapacityAnalysis（直接累加字段）
         * =============================================================
         */
        TransportCapacityAnalysis trans = new TransportCapacityAnalysis();

        Long normalCount = 0L;
        BigDecimal normalWeight = BigDecimal.ZERO;

        Long freezeCount = 0L;
        BigDecimal freezeWeight = BigDecimal.ZERO;

        Long dangerCount = 0L;
        BigDecimal dangerWeight = BigDecimal.ZERO;

        for (IndustrialLogisticsCompany c : companyList) {

            normalCount += Optional.ofNullable(c.getNormalCarCount()).orElse(0L);
            normalWeight = normalWeight.add(
                Optional.ofNullable(c.getNormalCarWeight()).orElse(BigDecimal.ZERO)
            );

            freezeCount += Optional.ofNullable(c.getFreezeCarCount()).orElse(0L);
            freezeWeight = freezeWeight.add(
                Optional.ofNullable(c.getFreezeCarWeight()).orElse(BigDecimal.ZERO)
            );

            dangerCount += Optional.ofNullable(c.getDangerousCarCount()).orElse(0L);
            dangerWeight = dangerWeight.add(
                Optional.ofNullable(c.getDangerousCarWeight()).orElse(BigDecimal.ZERO)
            );
        }

        trans.setGeneralVehicleCount(normalCount.intValue());
        trans.setGeneralVehicleTotalLoad(normalWeight.setScale(2, RoundingMode.HALF_UP).doubleValue());

        trans.setRefrigeratedVehicleCount(freezeCount.intValue());
        trans.setRefrigeratedVehicleTotalLoad(freezeWeight.setScale(2, RoundingMode.HALF_UP).doubleValue());

        trans.setHazardousMaterialsVehicleCount(dangerCount.intValue());
        trans.setHazardousMaterialsVehicleTotalLoad(dangerWeight.setScale(2, RoundingMode.HALF_UP).doubleValue());

        vo.setTransportCapacityAnalysis(trans);

        return vo;
    }


}
